
package com.rt.schedulenew.utils.coder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

public class AESCoder
{
    public static final String TRANSFORMATION_ECB = "AES/ECB/PKCS5Padding";
    public static final String TRANSFORMATION_CBC = "AES/CBC/PKCS5Padding";
    public static final String IV = "0102030405060708";
    public static final String CHARSET = "UTF-8";
    
    public static byte[] encrypt(final String content, final String password) throws Exception {
        try {
            final SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(password.getBytes());
            final KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, random);
            final SecretKey secretKey = kgen.generateKey();
            final byte[] enCodeFormat = secretKey.getEncoded();
            final SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            final Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            final byte[] byteContent = content.getBytes("UTF-8");
            cipher.init(1, key);
            final byte[] result = cipher.doFinal(byteContent);
            return result;
        }
        catch (Exception e) {
            throw e;
        }
    }
    
    public static byte[] decrypt(final byte[] content, final String password) throws Exception {
        try {
            final SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(password.getBytes("UTF-8"));
            final KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, random);
            final SecretKey secretKey = kgen.generateKey();
            final byte[] enCodeFormat = secretKey.getEncoded();
            final SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            final Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(2, key);
            final byte[] result = cipher.doFinal(content);
            return result;
        }
        catch (Exception e) {
            throw e;
        }
    }
    
    public static String encryptByCBC(final String content, final String password) throws Exception {
        final IvParameterSpec zeroIv = new IvParameterSpec("0102030405060708".getBytes());
        final SecretKeySpec key = getKey(password);
        final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(1, key, zeroIv);
        final byte[] encryptedData = cipher.doFinal(content.getBytes("UTF-8"));
        final String encryptResultStr = parseByte2HexStr(encryptedData);
        return encryptResultStr;
    }
    
    public static String decryptByCBC(String content, final String password) throws Exception {
        content = new String(content.getBytes("UTF-8"));
        final byte[] decryptFrom = parseHexStr2Byte(content);
        final IvParameterSpec zeroIv = new IvParameterSpec("0102030405060708".getBytes());
        final SecretKeySpec key = getKey(password);
        final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(2, key, zeroIv);
        final byte[] decryptedData = cipher.doFinal(decryptFrom);
        return new String(decryptedData, "UTF-8");
    }
    
    private static SecretKeySpec getKey(final String strKey) throws Exception {
        final byte[] arrBTmp = strKey.getBytes();
        final byte[] arrB = new byte[16];
        for (int i = 0; i < arrBTmp.length && i < arrB.length; ++i) {
            arrB[i] = arrBTmp[i];
        }
        final SecretKeySpec skeySpec = new SecretKeySpec(arrB, "AES");
        return skeySpec;
    }
    
    public static String parseByte2HexStr(final byte[] buf) {
        final StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; ++i) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }
    
    public static byte[] parseHexStr2Byte(final String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        }
        final byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; ++i) {
            final int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            final int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte)(high * 16 + low);
        }
        return result;
    }
    
    public static void main(final String[] args) throws Exception {
        final String password = "1472583690ABCDEF";
        String str1 = encryptByCBC("1234567890123456", password);
        System.out.println("加密：" + str1);
        str1 = decryptByCBC("889c4ebdba40d201007b9da5ae265204fb07d03f20d3d6a9c03ff7305a7b5274", password);
        System.out.println("解密：" + str1);
    }
}
